package com.xywh.wanandroid.ext


import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.xywh.wanandroid.event.EventViewModel.Companion.openLoadingDialog
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import me.hgj.jetpackmvvm.base.viewmodel.BaseViewModel
import me.hgj.jetpackmvvm.ext.executeResponse
import me.hgj.jetpackmvvm.ext.util.loge
import me.hgj.jetpackmvvm.network.AppException
import me.hgj.jetpackmvvm.network.BaseResponse
import me.hgj.jetpackmvvm.network.ExceptionHandle
import me.hgj.jetpackmvvm.state.ResultState


/**
 * 过滤服务器结果，失败抛异常
 * @param block 请求体方法，必须要用suspend关键字修饰
 * @param success 成功回调
 * @param error 失败回调 可不传
 * @param isShowDialog 是否显示加载框
 * @param loadingMessage 加载框提示内容
 */
fun <T : Any?> BaseViewModel.requestCompose(
    block: suspend () -> BaseResponse<T>,
    success: (T?) -> Unit,
    error: (AppException) -> Unit = {},
    isShowDialog: Boolean = false,
    loadingMessage: String = "请求网络中..."
): Job {
    //如果需要弹窗 通知Activity/fragment弹窗
    return viewModelScope.launch {
        runCatching {
            if (isShowDialog)
                openLoadingDialog.value = loadingMessage
            //请求体
            block()
        }.onSuccess {
            //网络请求成功 关闭弹窗
            openLoadingDialog.value = ""
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                executeResponse(it) { t ->
                    success(t)
                }
            }.onFailure { e ->
                //打印错误消息
                e.message?.loge()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            //网络请求异常 关闭弹窗
            openLoadingDialog.value = ""
            //打印错误消息
            it.message?.loge()
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }
}

/**
 * net request 不校验请求结果数据是否是成功
 * @param block 请求体方法
 * @param resultState 请求回调的ResultState数据
 * @param isShowDialog 是否显示加载框
 * @param loadingMessage 加载框提示内容
 */
fun <T> BaseViewModel.requestCompose(
    block: suspend () -> BaseResponse<T>,
    isShowDialog: Boolean = false,
    loadingMessage: String = "请求网络中...",
    error: (AppException) -> Unit = {},
): MutableLiveData<T> {
    val resultState = MutableLiveData<T>()
    viewModelScope.launch {
        runCatching {
            if (isShowDialog)
                openLoadingDialog.value = loadingMessage
            //请求体
            block()
        }.onSuccess {
            openLoadingDialog.value = ""
            openLoadingDialog.value = ""
            runCatching {
                //校验请求结果码是否正确，不正确会抛出异常走下面的onFailure
                executeResponse(it) { t ->
                    resultState.value = it.getResponseData()
                }
            }.onFailure { e ->
                //打印错误消息
                e.message?.loge()
                //失败回调
                error(ExceptionHandle.handleException(e))
            }
        }.onFailure {
            openLoadingDialog.value = ""
            //打印错误消息
            it.message?.loge()
            //失败回调
            error(ExceptionHandle.handleException(it))
        }
    }

    return resultState
}

fun <T> parseState(
    resultState: ResultState<T>,
    onSuccess: (T) -> Unit,
    onError: ((AppException) -> Unit)? = null,
    onLoading: (() -> Unit)? = null
) {
    when (resultState) {
        is ResultState.Loading -> {
            openLoadingDialog.value = resultState.loadingMessage
            onLoading?.invoke()
        }

        is ResultState.Success -> {
            try {
                openLoadingDialog.value = ""
                onSuccess(resultState.data)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        is ResultState.Error -> {
            openLoadingDialog.value = ""
            onError?.run { this(resultState.error) }
        }
    }
}
